import {Injectable} from '@angular/core';
import {OAuthService} from "angular-oauth2-oidc";

@Injectable({
  providedIn: 'root'
})
export class AclService {

  private roleCache = new Map<string, string[]>();
  // 假设：引入一个合理的缓存过期策略，这里简单地使用时间戳
  private cacheExpiry = new Map<string, number>();


  // 优化：实现缓存逻辑和过期机制
  private isCacheValid(cacheKey: string): boolean {
    const expiryTime = this.cacheExpiry.get(cacheKey);
    return !expiryTime || expiryTime > Date.now();
  }

  private updateCacheExpiry(cacheKey: string): void {
    this.cacheExpiry.set(cacheKey, Date.now() + 10 * 60 * 1000); // 10分钟缓存过期
  }

  constructor(private oauthService: OAuthService) { }

  //获取授权
  async getUserRoles(): Promise<string[]> {
    try {
      if (!this.oauthService.hasValidAccessToken() || !this.oauthService.hasValidIdToken()) {
        return [];
      }

      // 安全地获取identity claims以避免null或undefined的问题
      const idTokenClaims = await this.oauthService.getIdentityClaims();
      if (!idTokenClaims) {
        console.error('Identity claims are not available.');
        return [];
      }

      // 改进缓存键的生成逻辑，确保安全和效用
      // 注意：这里需要确保选取的属性不包含敏感信息
      // @ts-ignore
      const cacheKey = JSON.stringify({sub: idTokenClaims.sub,sid: idTokenClaims.sid}).toString() || 'default';
      if (this.roleCache.has(cacheKey) && this.isCacheValid(cacheKey)) {
        console.log('Using cached key:', cacheKey);
        return this.roleCache.get(cacheKey)!;
      }

      //return idTokenClaims?.authorities || [];  //authorities?.realm_access?.roles
      // 明确地处理authorities的类型问题，避免@ts-ignore
      // @ts-ignore
      const authorities = idTokenClaims?.authorities || [];
      this.roleCache.set(cacheKey, authorities);
      this.updateCacheExpiry(cacheKey);
      return authorities;
    } catch (error) {
      console.error('Error fetching user roles:', error);
      // 引入错误上报或处理机制
      // this.errorService.log(error);
      return [];
    }
  }

  private cachedRoles: string[] | null = null;
//  Promise<
  async hasRole(role: string): Promise<boolean> {

    // 尝试从缓存中获取roles，如果缓存未命中，则调用getUserRoles
    if (this.cachedRoles === null) {
      try {
        this.cachedRoles = await this.getUserRoles();
      } catch (error) {
        console.error("Failed to fetch user roles:", error);
        // 根据业务需求决定是否需要重新抛出异常、记录日志或采取其他措施
        throw error; // 或者返回false，取决于是否该角色的存在性对于当前操作是关键
      }
    }

    // 检查roles数组是否为空，如果为空，记录警告并返回false
    if (this.cachedRoles.length === 0) {
      console.warn("User roles list is empty.");
      return false;
    }
    console.info("User roles list is ===="+this.cachedRoles);
    // 使用includes检查role是否在数组中
    return this.cachedRoles.includes(role);
  }

  public hasRole2(role: string){this.hasRole(role).then(r => {console.log(r);});}

}
